// @ts-nocheck
import cornerstoneTools from "cornerstone-tools"
import cornerstone from "cornerstone-core"
import { drawBrushPixels } from "./segmentation/drawBrush"
import { pivotImagePointArrayTo3D } from "./segmentation/pivoters"
import { restoreImagePointArray, getLabelmap2DPatch } from "./utils/patch"
import { saveMaskAnnoData } from '@/api/readPathology/readPathology';
import {ElMessage} from "element-plus";
import { useFilmReadHeader, useFilmReadRight, useFilmReadLeft, useFilmRead } from '@/store'
import useUtils from "@/views/filmRead/hooks/useUtils";
import useLeft from "@/views/filmRead/hooks/useLeft";

/*const filmReadHeader = useFilmReadHeader()
const filmReadRight = useFilmReadRight()
const filmReadLeft = useFilmReadLeft()*/
const FilmRead = useFilmRead()
const BaseBrushTool = cornerstoneTools.import("base/BaseBrushTool")
const segmentationModule = cornerstoneTools.getModule("segmentation")
const { getDiffBetweenPixelData, triggerLabelmapModifiedEvent } = cornerstoneTools.import("util/segmentationUtils")
const { getToolState } = cornerstoneTools

export default class SyncBrushTool extends BaseBrushTool {
  static toAddLesionMasks = [] // 创建病灶的mask集合
  static toUpdateLesionMasks = [] // 编辑病灶的mask集合
  // static endLayer = 0 // 从当前层跨到第几层(使用自由画笔工具时选择了跨几层)
  static crossLayer = 1 //自由画笔工具选择了跨几层
  static thePreviousLesion = {isSave: true} // 临时存一下上一次选中过的病灶(校验其是否保存)

  constructor(props = {}) {
    const defaultProps = {
      name: "SyncBrush",
      supportedInteractionTypes: ["Mouse", "Touch"],
      mixins: ["renderBrushMixin"],
      /*configuration: {
        alwaysEraseOnClick: true
      }*/
    }
    super(props, defaultProps)
    this.touchDragCallback = this._paint.bind(this)
  }

  _startPainting(evt) {
    const LeftHooks = useLeft();
    const { configuration, getters, state } = segmentationModule
    const eventData = evt.detail
    const sourceElement = eventData.element
    const sourceImage = eventData.image
    const shouldErase =
      this._isCtrlDown(eventData) || configuration.alwaysEraseOnClick
    const toolData = getToolState(sourceElement, "Crosshairs")
    if (!toolData) {
      return
    }
    this.filterData = {
      sourcePixelData: sourceImage.getPixelData(),
      mode: configuration.mode || "plain",
      adaptCache: null,
      closeSize: configuration.closeSize || 1,
      openSize: configuration.openSize || 1,
      reverseOn: configuration.reverseOn || false,
      radius: configuration.radius || 10,

      thresholdOn: configuration.thresholdOn || false,
      thresholdMeta: configuration.thresholdMeta,
    }
    const {
      labelmap3D,
      labelmap2D,
      activeLabelmapIndex,
      currentImageIdIndex,
    } = getters.labelmap2D(sourceElement);
    
    // 新创建病灶时需清空
    (!LeftHooks.leftHooksData.currentIndex || !labelmap2D.pixelData.abc) && (labelmap2D.pixelData.abc = []);
    if(!configuration.customParams){
      configuration.customParams = {}
    }
    configuration.customParams.layerStart = currentImageIdIndex
    configuration.customParams.layerEnd = currentImageIdIndex + SyncBrushTool.crossLayer -1
    
    this.paintEventData = {
      labelmap3D,
      labelmap2D,
      activeLabelmapIndex,
      currentImageIdIndex,
      shouldErase,
    }
    if (configuration.storeHistory) {
      const previousPixelData = this.paintEventData.labelmap2D.pixelData.slice()
      this.paintEventData.previousPixelData = previousPixelData
    }
  }

  _paint(evt) {
    const { configuration: { radius }, getters } = segmentationModule
    const eventData = evt.detail
    const sourceElement = eventData.element
    const sourceImage = eventData.image
    const sourceImagePoint = eventData.currentPoints.image
    const { rows, columns } = sourceImage
    if (
      sourceImagePoint.x < 0 ||
      sourceImagePoint.x > columns ||
      sourceImagePoint.y < 0 ||
      sourceImagePoint.y > rows
    ) {
      return
    }
    const { labelmap2D, labelmap3D, shouldErase, currentImageIdIndex } = this.paintEventData
    const labelmap2DPatch = getLabelmap2DPatch(
      rows,
      columns,
      Math.round(sourceImagePoint.x),
      Math.round(sourceImagePoint.y),
      this.filterData,
    )
    const sourceImagePointArray = restoreImagePointArray(labelmap2DPatch)
    const activeColorLUTIndex = this.paintEventData.activeLabelmapIndex
    const { layerStart, layerEnd } = segmentationModule.configuration.customParams
    for(let i = layerStart; i < layerEnd +1; i++){
      const labelmap2DLayer = getters.labelmap2DByImageIdIndex(labelmap3D, i, rows, columns)
      drawBrushPixels(
          sourceImagePointArray,
          labelmap2DLayer.pixelData,
          labelmap3D.activeSegmentIndex,
          activeColorLUTIndex,
          columns,
          shouldErase,
          true,
          currentImageIdIndex
      )
    }
    
    cornerstone.updateImage(sourceElement)

    const stackToolDataSource = getToolState(sourceElement, "stack")
    if (stackToolDataSource === undefined) {
      return
    }
    const stackData = stackToolDataSource.data[0]
    const sourceImageIdIndex = stackData.currentImageIdIndex

    const toolData = getToolState(sourceElement, "Crosshairs")
    if (!toolData) {
      return
    }

    // brush other views accordingly
    const syncContext = toolData.data[0]?.synchronizationContext
    if (!syncContext) return
    const syncElements = syncContext.getSourceElements()
    syncElements.forEach((targetElement) => {
      if (targetElement === sourceElement) {
        return
      }
      const { labelmap3D } = getters.labelmap2D(targetElement)

      const stackToolDataSource = getToolState(targetElement, "stack")
      if (stackToolDataSource === undefined) {
        return
      }
      const stackData = stackToolDataSource.data[0]
      const baseImageId = stackData.imageIds[0]
      const { rows, columns } = cornerstone.metaData.get(
        "imagePlaneModule",
        baseImageId,
      )
  
      for(let i = layerStart; i < layerEnd +1; i++) {
        const imagePointArrayGroup = pivotImagePointArrayTo3D(
            sourceImagePointArray,
            i,
            columns,
            targetElement.id,
        )
        for (let key in imagePointArrayGroup) {
          try {
            const imageIdIndex = Number(key)
            const imagePointArray = imagePointArrayGroup[key]
            const labelmap2DForImageIdIndex = getters.labelmap2DByImageIdIndex(
                labelmap3D,
                imageIdIndex,
                rows,
                columns,
            )
            drawBrushPixels(
                imagePointArray,
                labelmap2DForImageIdIndex.pixelData,
                labelmap3D.activeSegmentIndex,
                activeColorLUTIndex,
                columns,
                shouldErase,
                false
            )
          } catch (e) {
            console.log(e)
          }
        }
      }
      cornerstone.updateImage(targetElement)
    })
  }

  _endPainting(evt) {
    const { lesionEvent, seriesEvent } = useUtils();
    const LeftHooks = useLeft();
    const { configuration, setters } = segmentationModule
    const { labelmap2D, labelmap3D, currentImageIdIndex } = this.paintEventData
    const segmentSet = new Set(labelmap2D.pixelData)
    const iterator = segmentSet.values()

    const segmentsOnLabelmap = []
    let done = false
    while (!done) {
      const next = iterator.next()
      done = next.done
      if (!done) {
        segmentsOnLabelmap.push(next.value)
      }
    }
    //更新segments
    const { layerStart, layerEnd } = segmentationModule.configuration.customParams
    for(let i = layerStart; i < layerEnd +1; i++) {
      labelmap3D.labelmaps2D[i].segmentsOnLabelmap = segmentsOnLabelmap
    }

    if (configuration.storeHistory) {
      const { previousPixelData } = this.paintEventData
      const newPixelData = labelmap2D.pixelData
      const operation = {
        imageIdIndex: currentImageIdIndex,
        diff: getDiffBetweenPixelData(previousPixelData, newPixelData),
      }
      setters.pushState(this.element, [operation])
    }
    this.filterData = null

    triggerLabelmapModifiedEvent(this.element)
    const editedPixelDataIndexList = labelmap2D.pixelData.abc
    if (configuration.alwaysEraseOnClick || LeftHooks.leftHooksData.currentIndex !== '') { // 橡皮擦或者当前选中了某个病灶
      const lesion = FilmRead.dictionaryData.lesionDataList[LeftHooks.leftHooksData.currentIndex]
      if(lesion.tool === 'FREEHAND_DAUBER'){
        SyncBrushTool.thePreviousLesion.isSave = false
        /*const lesionMask = SyncBrushTool.toUpdateLesionMasks.find(({ layer }) => layer === currentImageIdIndex)
        if (!lesionMask) {
          SyncBrushTool.toUpdateLesionMasks.push({
            layer: currentImageIdIndex,
            result: editedPixelDataIndexList
          })
          //有个bug(编辑时涂抹工具选择的跨多层, 不能实现多层保存)
        } else {
          lesionMask.result = editedPixelDataIndexList
        }*/
        return false
      }else{
        return
      }
    }else{
      SyncBrushTool.thePreviousLesion.isSave = true
    }
    const finalParams = Object.assign({}, configuration.customParams, {
      result: editedPixelDataIndexList
    })
    const imageCompList = configuration.imageCompList
    //todo 参数改成多层的数据,创建时暂时一层？
    // return
    saveMaskAnnoData(finalParams).then(res => {
      const alrId = res.alrId || res.data.alrId
      ElMessage.success('创建病灶成功')
      // filmReadHeader.refresh()
      // filmReadRight.setCurrentItem(alrId.toString())
      // filmReadLeft.setCurrentLesion(alrId)
      const { lesion,tool,layerStart,layerEnd,result } = finalParams
      //创建时本地的涂抹数据，多层
      let layerDataArr = []
      for(let i = layerStart; i < layerEnd +1; i++){
        layerDataArr.push({color: null, groupId: "", id:0, layer: i, result: JSON.stringify(result), resultType: 1, tool: null})
      }
      lesionEvent.lesionAdd( {id: alrId, code: lesion, index:0,eyeStatus: true,lesion,tool,result: layerDataArr,layerStart,layerEnd, imageCompList})
      //set alrId for labelmap3D
      this.paintEventData.labelmap3D.uuid = alrId
    })
  }

  mouseDragCallback(evt) {
    const { currentPoints } = evt.detail
    this._lastImageCoords = currentPoints.image
    if (this._drawing) {
      this._paint(evt)
    }
  }

  preMouseDownCallback(evt) {
    evt.stopImmediatePropagation()
    const eventData = evt.detail
    const { element, currentPoints } = eventData
    this._startPainting(evt)
    this._lastImageCoords = currentPoints.image
    this._drawing = true
    this._startListeningForMouseUp(element)
    this._paint(evt)
    return true
  }
}
